/***************************************************************************
 *            util.c
 *
 *  jue junio 14 19:29:34 2012
 *  Copyright  2012  Kellerman Rivero
 *  <user@host>
 ****************************************************************************/
/*
 * util.c
 *
 * Copyright (C) 2012 - Kellerman Rivero
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */


#include "util.h"

Lista *Lista_InsertarInicio (Lista **inicio, void* nodo){
    Lista *q=(Lista*)malloc(sizeof(Lista));
    if(q!=NULL){
	  q->algo=nodo;
      q->siguiente=*inicio;
      *inicio = q;
    } else printf("Memoria no Disponible \n");
    return *inicio;
}

Lista *Lista_EliminarInicio (Lista **inicio){ 
    if (inicio != NULL){
      Lista *q;
      q = *inicio;
      *inicio = (*inicio)->siguiente;
      free(q);
      return *inicio;
    } else return NULL;
}

Lista *Lista_InsertarFinal (Lista **inicio, void* nodo){
   Lista *q=(Lista*)malloc(sizeof(Lista));;
   if (*inicio != NULL){
     Lista *w; w = *inicio;
     while ( w->siguiente != NULL)
        w = w->siguiente;
     if(q!=NULL){
		q->algo=nodo;
	  	q->siguiente=NULL;
		w->siguiente = q;
     } else printf("Memoria no Disponible \n");
     return *inicio;
   } else {
     	Lista_InsertarInicio(inicio,q);
     return *inicio;
   }
}

Lista *Lista_EliminarFinal (Lista **inicio){
  Lista *q,*w;
  if (*inicio != NULL){
    if((*inicio)->siguiente == NULL) Lista_EliminarInicio(inicio);
    else {
      w = *inicio; 
      while (w->siguiente != NULL){
		  q = w;
		  w = w -> siguiente;
      }
      q -> siguiente = NULL;
      free(w); 
    }
    return *inicio;
  } else return NULL;
}

Lista *Lista_Inicializar(Lista **inicio){
  *inicio = NULL;
  return *inicio;
}

Lista *Lista_Liberar(Lista **inicio){
  if (*inicio != NULL){
  while((*inicio)->siguiente != NULL)
    Lista_EliminarInicio(inicio);
    Lista_Inicializar(inicio);
  }
  return *inicio;
}

Lista *Lista_Eliminar(Lista** lista, void* nodo, int (*Criterio)(void*,void*,int), int* resultado){
	if(resultado!=NULL) *resultado=0;
	if((lista!=NULL)&&(*lista!=NULL)){
		Lista *inicio=*lista;
		Lista *anterior=inicio;
		while((inicio!=NULL)&&(!Criterio(inicio->algo,nodo,ComparacionSimple))){
			anterior=inicio;
			inicio=inicio->siguiente;
		}
		if((inicio!=NULL)&&(Criterio(inicio->algo,nodo,ComparacionSimple))){
		 	if(resultado!=NULL) *resultado=1;
			if(anterior=inicio){
				*lista=inicio->siguiente;
			}else{
				anterior->siguiente=inicio->siguiente;
			}
			free(inicio);
		}
	}
	return *lista;
}

Lista *Lista_BusquedaSimple(Lista** lista, void* nodo, int(*Criterio)(void*,void*,int),int *encontrado,int *indice){
	if(indice!=NULL) *indice=0;
	if(encontrado!=NULL) *encontrado=0;
	if((*lista!=NULL)&&(nodo!=NULL)){
		Lista *inicio=*lista;
		while((inicio!=NULL)&&(!Criterio(inicio->algo,nodo,ComparacionSimple))){
			if(indice!=NULL)
				*indice+=1;
			inicio=inicio->siguiente;
		}
		if((inicio!=NULL)&&(Criterio(inicio->algo,nodo,ComparacionSimple))){
			*encontrado=1;
		 	return inicio;
		}
	}
	if(indice!=NULL) *indice=-1;
	return *lista;
}

Lista *Lista_BusquedaFull(Lista** lista, void* nodo, int(*Criterio)(void*,void*,int),int *encontrado,int *indice){
	if(indice!=NULL) *indice=-1;
	if(encontrado!=NULL) *encontrado=0;
	if((*lista!=NULL)&&(nodo!=NULL)){
		Lista *inicio=*lista;
		while((inicio!=NULL)&&(!Criterio(inicio->algo,nodo,ComparacionFull))){
			if(indice!=NULL)
				*indice+=1;
			inicio=inicio->siguiente;
		}
		if((inicio!=NULL)&&(Criterio(inicio->algo,nodo,ComparacionFull))){
			*encontrado=1;
		 	return inicio;
		}
	}
	return *lista;
}

void Lista_Imprimir(Lista **lista, void (Imprimir)(void*)){
	if((lista!=NULL)&&(*lista!=NULL)){
		Lista *inicio = *lista;
		while(inicio!=NULL){
			Imprimir(inicio->algo);
			inicio=inicio->siguiente;
		}
	}else printf("Vacio\n");
}